// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.ExperimentalAnimationApi
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.desktop.DesktopMaterialTheme
import androidx.compose.desktop.ui.tooling.preview.Preview
import androidx.compose.foundation.background
import androidx.compose.foundation.gestures.scrollable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material.*
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Close
import androidx.compose.material.icons.filled.Menu
import androidx.compose.material.icons.filled.MoreVert
import androidx.compose.material.icons.filled.Send
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.Window
import androidx.compose.ui.window.WindowSize
import androidx.compose.ui.window.WindowState
import androidx.compose.ui.window.application
import com.paullorenc.rose.desktop.OutgoingMessageBus
import com.paullorenc.rose.desktop.conversation.ConversationViewModel
import com.paullorenc.rose.desktop.interfaces.LoraInterface
import kotlinx.coroutines.*
import java.time.Instant
import java.time.LocalDate
import java.time.LocalTime
import java.util.*

@OptIn(ExperimentalAnimationApi::class)
@Composable
@Preview
fun App() {
    var infoScreenVisible by remember { mutableStateOf(false) }
    var sendDelay by remember { mutableStateOf("0") }
    var sendIterations by remember { mutableStateOf("1") }
    var iterationInterval by remember { mutableStateOf("0") }
    val hr = LoraInterface
    val vm = ConversationViewModel
    starter()
    DesktopMaterialTheme {
        var text by remember { mutableStateOf("") }
        Box(Modifier.fillMaxSize()) {
            Scaffold(
                topBar = {
                    Card(elevation = 12.dp) {
                        Box(Modifier.fillMaxWidth().height(52.dp).background(color = MaterialTheme.colors.primary)) {
                            Text("Test Channel", modifier = Modifier.align(Alignment.Center), color = MaterialTheme.colors.onPrimary)
                            IconButton(onClick = {infoScreenVisible = true}, modifier = Modifier.align(Alignment.CenterEnd)) {
                                Icon(Icons.Filled.MoreVert, "info button", tint = MaterialTheme.colors.onPrimary)
                            }
                        }
                    }
                },
                bottomBar = {
                    TextField(
                        value = text,
                        onValueChange = { if(it.length < 230) text = it },
                        placeholder = { Text("Message") },
                        trailingIcon = {IconButton({send(text, sendDelay.toLong(), sendIterations.toInt(), iterationInterval.toLong()); text=""}) {Icon(Icons.Filled.Send, "send") }},
                        modifier = Modifier.fillMaxWidth()
                    )
                },
                content = { padding ->
                    LazyColumn(
                        verticalArrangement = Arrangement.spacedBy(8.dp),
                        // reverseLayout to display most recent message (index 0) at the bottom
                        contentPadding = PaddingValues(8.dp),
                        modifier = Modifier.padding(padding).fillMaxHeight()
                    ) {
                        items(vm.messages) { m ->
                            if (m.self) {
                                Text(m.msg, color = MaterialTheme.colors.primary)
                            } else {
                                Text(m.msg)
                            }
                        }
                    }
                },
            )
            AnimatedVisibility(visible = infoScreenVisible, enter = fadeIn(), exit = fadeOut()) {
                Box(Modifier.fillMaxSize().background(MaterialTheme.colors.background)) {
                    IconButton(onClick = {infoScreenVisible = false}, Modifier.align(Alignment.TopStart)) {
                        Icon(Icons.Filled.Close, "close info screen")
                    }
                    Column(verticalArrangement = Arrangement.spacedBy(4.dp), modifier = Modifier.fillMaxWidth().align(Alignment.TopCenter).padding(start = 16.dp)) {
                        Spacer(Modifier.fillMaxWidth().height(52.dp))
                        Row(Modifier.fillMaxWidth()) {
                            Text("Send Delay", modifier = Modifier.width(192.dp))
                            TextField(sendDelay, onValueChange = {it -> sendDelay = it}, keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number), modifier = Modifier.width(160.dp))
                        }
                        Row(Modifier.fillMaxWidth()) {
                            Text("Re-Broadcast Number", modifier = Modifier.width(192.dp))
                            TextField(sendIterations, onValueChange = {it -> sendIterations = it}, keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number), modifier = Modifier.width(160.dp))
                        }
                        Row(Modifier.fillMaxWidth()) {
                            Text("Re-Broadcast Interval", modifier = Modifier.width(192.dp))
                            TextField(iterationInterval, onValueChange = {it -> iterationInterval = it}, keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number), modifier = Modifier.width(160.dp))
                        }
                    }
                }
            }
        }
    }
}
fun starter() {
    GlobalScope.launch(Dispatchers.Default) {
        LoraInterface.start()
    }
}

fun send(string: String, sendDelay: Long = 0, rebroadcast: Int = 1, rebroadcastInterval: Long = 0) {
    GlobalScope.launch(Dispatchers.IO) {
        val now = LocalTime.now().toString()
        var i = 0;
        delay(sendDelay)
        while(i < rebroadcast) {
            OutgoingMessageBus.postMessage(now + ": " + string)
            delay(rebroadcastInterval)
            i++
        }
    }
}

fun main() = application {
    Window(title = "ROSE Mesh Messenger", onCloseRequest = ::exitApplication, state = WindowState(size = WindowSize(400.dp, 600.dp))) {
        App()
    }
}
